#include "desktop.h"

Desktop::Desktop(QWidget *parent) : QOpenGLWidget(parent)
{
    oglManager = nullptr;
    deltaTime = 0.0f;
    lastFrame = 0.0f;

    isFirstMouse = GL_TRUE;
    isLeftMousePress = GL_FALSE;
    lastX = width() / 2.0f;
    lastY = height() / 2.0f;
}

Desktop::~Desktop()
{
    makeCurrent();

    if (oglManager != nullptr)
    {
        delete oglManager;
    }
}

void Desktop::handleKeyPressEvent(QKeyEvent *event)
{
    GLuint key = event->key();

    if (key <= 1024)
    {
        oglManager->keys[key] = GL_TRUE;
    }
}

void Desktop::handleKeyReleaseEvent(QKeyEvent *event)
{
    GLuint key = event->key();

    if (key <= 1024)
    {
        oglManager->keys[key] = GL_FALSE;
    }
}

GLboolean Desktop::loadModel(const QString &file)
{
    return oglManager->loadModel(file);
}

void Desktop::initializeGL()
{
    init();
    time.start();
}

void Desktop::resizeGL(int w, int h)
{
    oglManager->resize(w, h);
}

void Desktop::paintGL()
{
    const GLfloat currentFrame = (GLfloat) time.elapsed() / 100.0f;
    deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;

    oglManager->processInput(deltaTime);
    oglManager->update(deltaTime);
    oglManager->draw(deltaTime);

    update();
}

void Desktop::wheelEvent(QWheelEvent *event)
{
    QPoint offset = event->angleDelta();
    oglManager->camera->processMouseScroll(offset.y() / 20.0f);
//    update();
}

void Desktop::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) //注意是button（）不是buttons（）；
    {
        isLeftMousePress = GL_TRUE;
    }
}

void Desktop::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) //注意是button（）不是buttons（）；
    {
        isLeftMousePress = GL_FALSE;
        isFirstMouse = GL_TRUE;
    }
}

void Desktop::mouseMoveEvent(QMouseEvent *event)
{
    GLint xpos = event->pos().x();
    GLint ypos = event->pos().y();

    if (isLeftMousePress)
    {
        if (isFirstMouse)
        {
            lastX = xpos;
            lastY = ypos;
            isFirstMouse = GL_FALSE;
        }

        GLint xoffset = xpos - lastX;
        GLint yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
        lastX = xpos;
        lastY = ypos;
        oglManager->camera->processMouseMovement(xoffset, yoffset);
//        update();
    }
}

GLboolean Desktop::init()
{
    oglManager = new OGLManager(this->width(), this->height());
    if (nullptr == oglManager)
    {
        // todo log error
        return GL_FALSE;
    }

    if (!oglManager->init())
    {
        delete oglManager;
        oglManager = nullptr;

        return GL_FALSE;
    }

    return GL_TRUE;
}
